home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 402_01 / cforms-2.2 / src / token.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-20  |  5.3 KB  |  280 lines

  1. /*******************************************************************************
  2. *
  3. *        T O K E N . C
  4. *        -------------
  5. *
  6. * Description:
  7. *    Reads tokens from input file. Tokens are the C-stype tokens. It is
  8. *    allso possible to unget tokens for later recall by GetTok().
  9. *
  10. * Included functions:
  11. *    GetTok()    - Get token
  12. *
  13. *
  14. * Revision:
  15. *    Ver    Date   By        Reason
  16. *    ---    ----   --        ------
  17. *    1.00   900619 Lars Berntzon    Created
  18. *
  19. ******************************************************************************/
  20. #ifndef lint
  21. static volatile char sccs_id[] = "@(#) token.c,v 1.6 1993/05/13 21:55:48 lasse Exp";
  22. #endif
  23.  
  24. #include "config.h"
  25. #include "token.h"
  26.  
  27. #define isnormal(c) (isalnum(c) || (c) == '_')
  28.  
  29.     /* T y p e s */
  30. typedef enum { st_init,
  31.            st_normal,
  32.            st_searching_quote,
  33.            st_got_slash,
  34.            st_got_comment,
  35.            st_got_star,
  36.            st_searching_endcomment,
  37.            st_got_backslash } state_t;
  38.  
  39.     /* G l o b a l   v a r i a b l e s */
  40.     
  41. int line = 1;           /* Current line number            */
  42. FILE *in;           /* The input file pointer            */
  43.  
  44.     /* L o c a l   v a r i a b l e */
  45.  
  46. static int ch = 0;        /* Next input character            */
  47.  
  48.  
  49. /*******************************************************************************
  50.  *
  51.  *        G E T O K 
  52.  *        ---------
  53.  *
  54.  * Description:
  55.  *    Reads one token from input file (skips c type comments).
  56.  *
  57.  * Output:
  58.  *    ret_token    - String where data wil be put (if not NULL).
  59.  *    ret_space    - Space string found before token (if not NULL).
  60.  *
  61.  * Return:
  62.  *    String containing token, NULL if end of file.
  63.  *
  64.  ******************************************************************************/
  65. char *
  66. GetTok(char *ret_token, char *ret_space)
  67. {
  68.     static char token[TOKENSIZE];    /* Where read token is stored        */
  69.     static char space[TOKENSIZE];    /* Where spaces before token is stored    */
  70.     int token_pos = 0;            /* Current token write position        */
  71.     int space_pos = 0;            /* Current space positions        */
  72.     state_t state = st_init;        /* Current state            */
  73.     
  74.     /*
  75.      * Read first char of file.
  76.      */
  77.     if (ch == 0) {
  78.     ch = getc(in);
  79.     }
  80.     
  81.     if (ch == EOF) return NULL;
  82.     
  83.     for(; ch != EOF; ch = getc(in))
  84.     {
  85.     if (ch == '\n')
  86.     {
  87.         line++;
  88.     }
  89.  
  90.     switch(state) 
  91.     {
  92.     case st_init:
  93.         if (isspace(ch)) {
  94.         space[space_pos++] = ch;
  95.             break;
  96.         }
  97.         else if (ch == '"') {
  98.         token[token_pos++] = ch;
  99.         state = st_searching_quote;
  100.         }
  101.         else if (ch == '/') {
  102.         token[token_pos++] = ch;
  103.         state = st_got_slash;
  104.         }
  105.         else if (!isnormal(ch)) {
  106.         token[token_pos++] = ch;
  107.         token[token_pos++] = 0;
  108.         ch = 0;
  109.         goto found;
  110.         }
  111.         else if (isnormal(ch)) {
  112.             token[token_pos++] = ch;
  113.             state = st_normal;
  114.         }
  115.         break;
  116.  
  117.     case st_normal:
  118.         if (isnormal(ch)) {
  119.             token[token_pos++] = ch;
  120.         }
  121.         else {
  122.         token[token_pos++] = 0;
  123.         goto found;
  124.         }
  125.         break;
  126.  
  127.     case st_searching_quote:
  128.         token[token_pos++] = ch;
  129.         if (ch == '\\') {
  130.             state = st_got_backslash;
  131.         }
  132.         else {
  133.             if (ch == '"') {
  134.                 token[token_pos++] = 0;
  135.                 ch = 0;
  136.                 goto found;
  137.             }
  138.         }
  139.         break;
  140.  
  141.     case st_got_backslash:
  142.         token[token_pos++] = ch;
  143.         state = st_searching_quote;
  144.         break;
  145.  
  146.     case st_got_slash:
  147.         if (ch == '*') {
  148.         state = st_got_comment;
  149.  
  150.         /*
  151.          * Remove the slash from token.
  152.          */
  153.         token_pos--;
  154.  
  155.         /*
  156.          * And save the comment in the space field instead.
  157.          */
  158.         space[space_pos++] = '/';
  159.         space[space_pos++] = '*';
  160.  
  161.         }
  162.         else {
  163.         goto found;
  164.         }
  165.         break;
  166.  
  167.     case st_got_comment:
  168.         if(ch == '*') {
  169.         state = st_got_star;
  170.         }
  171.         space[space_pos++] = ch;
  172.         break;
  173.  
  174.     case st_got_star:
  175.         space[space_pos++] = ch;
  176.         if (ch == '/') {
  177.         state = st_init;
  178.         }
  179.         else if (ch != '*') {
  180.         state = st_got_comment;
  181.         }
  182.         break;
  183.     
  184.     default:
  185.         fprintf(stderr, "unknown state in file %s line %d, this should not happen\n",
  186.         __FILE__, __LINE__);
  187.     }
  188.     }
  189.  
  190. found:
  191.     space[space_pos] = 0;
  192.     token[token_pos] = 0;
  193.  
  194.     if(ret_space) {
  195.     strcpy(ret_space, space);
  196.     }
  197.  
  198.     if (ret_token) {
  199.     strcpy(ret_token, token);
  200.     }
  201.     else {
  202.     ret_token = token;
  203.     }
  204.  
  205.     if (token_pos == 0) return NULL;
  206.  
  207.     return ret_token;
  208. }
  209.  
  210. /*******************************************************************************
  211.  *
  212.  *        O P E N T O K
  213.  *        -------------
  214.  *
  215.  * Description:
  216.  *    Open a file to read tokens from.
  217.  *
  218.  * Input:
  219.  *    name    - Name of file.
  220.  *
  221.  * Return:
  222.  *    Opened files pointer, of NULL if failure.
  223.  *
  224.  ******************************************************************************/
  225. FILE *OpenTok(char *name)
  226. {
  227.     if (in != NULL) {
  228.     fclose(in);
  229.     ch = 0;
  230.     }
  231.     return in = fopen(name, "r");
  232. }
  233.  
  234. #ifdef STANDALONE
  235. /*******************************************************************************
  236.  *
  237.  *        M A I N
  238.  *        -------
  239.  *
  240.  * Description:
  241.  *    Main routine when compiled as standalone.
  242.  *    This is only used for test.
  243.  *
  244.  ******************************************************************************/
  245.  
  246. main()
  247. {
  248.     char token[TOKENSIZE];
  249.     char space[TOKENSIZE];
  250.     char outstr[1000];
  251.     char *p;
  252.     
  253.     in = stdin;
  254.  
  255.     while(GetTok(token, space))
  256.     {
  257.     sprintf(outstr, "'%s'-'%s'-%d", token, space, line);
  258.     for(p = outstr; *p != NULL; p++)
  259.     {
  260.         switch (*p)
  261.         {
  262.         case '\n':
  263.         putchar('\\');
  264.         putchar('n');
  265.         break;
  266.  
  267.         case '\t':
  268.         putchar('\\');
  269.         putchar('t');
  270.         break;
  271.         
  272.         default:
  273.         putchar(*p);
  274.         }
  275.     }
  276.     putchar('\n');
  277.     }
  278. }
  279. #endif /* STANDALONE */
  280.